#include<ctime>
#include"BigNumber.h"
#include "Timer.h"
using namespace std;

int main()
{
      BigNum p,q,I(1),e(257),t,temp,n,d,a,b,c,O(0);//b为密文，c为解密后结果 
      string A;
      Timer mytime;   //定义时间类类型数据 
      srand((unsigned)time(NULL)); 
      
      cout<<"*********************************************************************"<<endl;
      cout<<"*                         王式RSA系统                               *"<<endl;     
      cout<<"* 1、产生两个素数p、q，并产生公钥n，私钥e取257                      *"<<endl;
      cout<<"* 2、利用扩展欧几里德算法计算解密密钥d,满足e*d=1(mod(p-1)*(q-1))    *"<<endl;
      cout<<"* 3、输入明文即要加密的字符集                                       *"<<endl;
      cout<<"* 4、将明文P (假设P是一个小于n的整数)加密为密文b，输出b             *"<<endl;
      cout<<"* 5、将密文d解密为明文c，输出c，结束程序                            *"<<endl;
      cout<<"* 附注：参考书籍--机械工业出版社的《数论概论》、清华大学版          *"<<endl;
      cout<<"*《C++程序设计》、《C程序设计》                                     *"<<endl; 
      cout<<"*********************************************************************"<<endl<<endl;
       
      cout<<"程序运行中···"<<endl<<endl; 
      mytime.start();  //计时开始       
      p.GeneratePrime();   //产生素数 
      q.GeneratePrime();
      while(p==q)   //判断两个素数不等 
          q.GeneratePrime();
      temp=p-I;
      t=q-I;
      t=t*temp;  
      cout<<"素数p(位数32*32)为："<<endl;   //输出素数 
      p.print(); 
      cout<<endl;
      cout<<"素数q(位数32*32)为："<<endl;
      q.print();
      cout<<endl;
      cout<<"公钥n(位数为64*32)为"<<endl;
      n=p*q;
      n.print();
      cout<<endl;
      cout<<"公钥e(十进制是257)为"<<endl;
      e.print();
      cout<<endl;
      d.ex_euclid(e,t);   //计算私钥d 
      cout<<"私钥d(位数为64*32)为"<<endl;
      d.print();
      cout<<endl;
      mytime.stop(); // 计时停止
	  mytime.running();//计算产生公钥私钥用的总时间
	  cout<<"产生公钥私钥时间\t"<<mytime.seconds()<<"\tseconds"<<endl;//输出产生公钥私钥所用总时间
      cout<<endl<<"请输入您要加密的字符串  "<<endl<<endl;
      getline(cin,A);
      mytime.reset();   //时间清零 
      mytime.start(); //计时开始
      a=BigNum(A);
      cout<<endl;
      b=a.power_mod(e,n);   //产生密文b 
      cout<<"生成密文如下"<<endl;
      b.print();
      cout<<endl;
      c=b.power_mod(d,n);   //解密 
      cout<<"解密后的结果为"<<endl<<endl;
      c.printS();
      mytime.stop(); // 计时停止
	  mytime.running();//计算产生素数用的总时间
	  cout<<endl<<"加密解密时间\t"<<mytime.seconds()<<"\tseconds"<<endl;//输出加密解密所用总时间
      cout<<endl;
  
      system("pause");
      return 0;
}

